#ifndef __KEY_HANDLE_H__
#define __KEY_HANDLE_H__

#include <iostream>
#include <conio.h>
#include <windows.h>
#include <map>

#include "Cursor.hpp"

#define PLACE_CHESS_KEY ' '

using namespace std;

class KeyHandle
{
public:
	KeyHandle()
	{
		HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
		DWORD mode;
		GetConsoleMode(hStdin, &mode);
		mode &= ~ENABLE_LINE_INPUT;
		mode &= ~ENABLE_ECHO_INPUT;
		SetConsoleMode(hStdin, mode);

		keyMap.insert(pair<char, function<void(void)>>('w', bind(&Cursor::move, &cursor, Cursor::UP)));
		keyMap.insert(pair<char, function<void(void)>>('W', bind(&Cursor::move, &cursor, Cursor::UP)));
		keyMap.insert(pair<char, function<void(void)>>(72, bind(&Cursor::move, &cursor, Cursor::UP)));

		keyMap.insert(pair<char, function<void(void)>>('s', bind(&Cursor::move, &cursor, Cursor::DOWN)));
		keyMap.insert(pair<char, function<void(void)>>('S', bind(&Cursor::move, &cursor, Cursor::DOWN)));
		keyMap.insert(pair<char, function<void(void)>>(80, bind(&Cursor::move, &cursor, Cursor::DOWN)));

		keyMap.insert(pair<char, function<void(void)>>('a', bind(&Cursor::move, &cursor, Cursor::LEFT)));
		keyMap.insert(pair<char, function<void(void)>>('A', bind(&Cursor::move, &cursor, Cursor::LEFT)));
		keyMap.insert(pair<char, function<void(void)>>(75, bind(&Cursor::move, &cursor, Cursor::LEFT)));

		keyMap.insert(pair<char, function<void(void)>>('d', bind(&Cursor::move, &cursor, Cursor::RIGHT)));
		keyMap.insert(pair<char, function<void(void)>>('D', bind(&Cursor::move, &cursor, Cursor::RIGHT)));
		keyMap.insert(pair<char, function<void(void)>>(77, bind(&Cursor::move, &cursor, Cursor::RIGHT)));
	}
	~KeyHandle()
	{
		HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
		DWORD mode;
		GetConsoleMode(hStdin, &mode);
		mode |= ENABLE_LINE_INPUT;
		mode |= ENABLE_ECHO_INPUT;
		SetConsoleMode(hStdin, mode);
	}
	void waitPlayerPlaceChess(Player* player)
	{
		int ch;
		bool success = false;
		if (_kbhit)
		{
			do
			{
				HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
				FlushConsoleInputBuffer(hStdin);

				ch = _getch();
				if (ch == PLACE_CHESS_KEY)
				{
					success = player->placeChess(cursor.getX(), cursor.getY());

				}
				else
				{
					auto it = keyMap.find(ch);
					if (it != keyMap.end())
					{
						auto handle = it->second;
						handle();
					}
				}
			} while (!success);
		}
	}

	int getCursorX() const
	{
		return cursor.getX();
	}

	int getCursorY() const
	{
		return cursor.getY();
	}

	void setCursorPos(int x, int y)
	{
		cursor.setPos(x, y);
	}
private:
	Cursor cursor;
	map<char, function<void(void)>> keyMap;
};

#endif // !__KEY_HANDLE_H__
